package org.wu.framework.play.platform.application.impl;

import org.apache.commons.compress.utils.IOUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.sound.sampled.*;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.stream.Stream;

@Service
public class MusicCombinerService {

    /**
     * 将上传的音乐文件循环指定次数并合并成新文件
     * @param file 上传的音频文件（WAV格式）
     * @param loopCount 循环次数
     * @return 合成后的音频文件
     */
    public File combineMusicLoops(MultipartFile file, int loopCount) 
            throws UnsupportedAudioFileException, IOException, LineUnavailableException {
        
        // 验证文件类型
        validateFile(file);
        
        // 创建临时文件保存上传的内容
        File tempInputFile = File.createTempFile("input_", ".wav");
        Files.copy(file.getInputStream(), tempInputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
        
        // 创建临时文件保存输出内容
        File tempOutputFile = File.createTempFile("output_", ".wav");
        
        // 执行合并操作
        combineMusicLoops(tempInputFile.getAbsolutePath(), 
                         tempOutputFile.getAbsolutePath(), 
                         loopCount);
        
        // 注册临时文件在JVM退出时删除
        tempInputFile.deleteOnExit();
        tempOutputFile.deleteOnExit();
        
        return tempOutputFile;
    }

    /**
     * 将音乐文件循环指定次数并合并成新文件
     * @param inputFilePath 输入音乐文件路径（WAV格式）
     * @param outputFilePath 输出音乐文件路径
     * @param loopCount 循环次数
     */
    public void combineMusicLoops(String inputFilePath, String outputFilePath, int loopCount)
            throws UnsupportedAudioFileException, IOException, LineUnavailableException {
        
        if (loopCount <= 0) {
            throw new IllegalArgumentException("循环次数必须大于0");
        }

        // 读取输入音频文件
        File inputFile = new File(inputFilePath);
        AudioInputStream inputAudioStream = AudioSystem.getAudioInputStream(inputFile);
        AudioFormat format = inputAudioStream.getFormat();
        
        // 获取输入音频的长度（帧数）
        long frameLength = inputAudioStream.getFrameLength();
        if (frameLength == AudioSystem.NOT_SPECIFIED) {
            throw new IOException("无法确定音频长度");
        }

        // 计算输出音频的总帧数
        long totalFrameLength = frameLength * loopCount;
        
        // 创建重复的音频流序列
        SequenceInputStream sequenceInputStream = createRepeatingSequence(inputAudioStream, loopCount);
        
        // 创建组合后的音频输入流
        AudioInputStream combinedAudioStream = new AudioInputStream(
            sequenceInputStream,
            format,
            totalFrameLength
        );

        // 写入输出文件
        AudioSystem.write(combinedAudioStream, AudioFileFormat.Type.WAVE, new File(outputFilePath));
        
        // 关闭流
        combinedAudioStream.close();
        inputAudioStream.close();
    }



    /**
     * 创建重复播放的音频流序列
     */
    private SequenceInputStream createRepeatingSequence(AudioInputStream audioStream, int loopCount)
            throws IOException, UnsupportedAudioFileException {

        // 创建音频流列表
        List<AudioInputStream> streams = new ArrayList<>();
        for (int i = 0; i < loopCount; i++) {
            // 每次循环都创建一个新的音频输入流
            AudioInputStream clonedStream = AudioSystem.getAudioInputStream(
                    new ByteArrayInputStream(IOUtils.toByteArray(audioStream))
            );
            streams.add(clonedStream);
        }

        // 将List转换为Enumeration
        Enumeration<AudioInputStream> streamEnum = Collections.enumeration(streams);

        return new SequenceInputStream(streamEnum);
    }
    /**
     * 验证上传的文件是否为WAV格式
     */
    private void validateFile(MultipartFile file) {
        if (file.isEmpty()) {
            throw new IllegalArgumentException("上传的文件不能为空");
        }
        
        String contentType = file.getContentType();
        if (contentType == null || !contentType.equals("audio/wav")) {
            throw new IllegalArgumentException("仅支持WAV格式的音频文件");
        }
        
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || !originalFilename.toLowerCase().endsWith(".wav")) {
            throw new IllegalArgumentException("文件名称必须以.wav结尾");
        }
    }
}
    